'''
Created on 21/03/2012

@author: laarguelless
'''

import random
 
class GrammarControl:
    
    def __init__(self,axiom,rule,turtle,screen,angle, iterations, random, initialstep,factor,color):
        self.__axiom = axiom        
        self.__rulekeys = None
        self.__rules = {}
        self.setRule(rule)               
        self.__turtle = turtle
        self.__alpabeth = ("F","|","G","+","-","[","]")
        self.__coordinates = []
        self.__screen = screen
        self.__random = random
        self.__step = initialstep
        self.__factor = factor
        self.__angle = angle
        self.__randomRata = 1
        self.__iterations = iterations
        self.__depth = 1
        self.__color = color
        self.__colors = []
         
    
    def verifyAxiom(self):
        if(len(self.__axiom) == 0):
            return False
        for x in self.__axiom:
            if(x not in self.__alpabeth and x not in self.__rulekeys):
                return False       
        return True
    
    def setRule(self,rule):        
        try:
            split_semicolon = rule.split(";")
            for x in split_semicolon:
                split_equal = x.split("=")
                self.__rules[split_equal[0]] = split_equal[1]
                self.__rulekeys = self.__rules.keys()
                print(self.__rules)
        except IndexError:
            return False
        
        
    
    def verifyRule(self): 
        print(self.__rules)       
        if(len(self.__rules) == 0):
            return False
        count = 0
        for key in self.__rulekeys:
            if(key not in self.__alpabeth):
                return False
            for symbol in self.__rules[key]:
                if (symbol not in self.__alpabeth):
                    return False
                if(key == "["):
                    count += 1
                elif(key == "]"):
                    count -= 1        
            if(count != 0):
                return False
        return True
    
    def setInstructions(self):    
        temp = ""
        try:            
            for x in self.__axiom:
                if x in self.__rulekeys:
                    temp += self.__rules[x]
                else:
                    temp += x
            self.__axiom = temp
        except KeyError:
            pass
    
    def mappingIntructions(self,symbol):
        #"F","|","G","+","-","[","]","H"
        if(self.__color):
            try:
                self.__turtle.color(self.__colors[self.__depth - 1 ])
            except IndexError:
                pass
        if(self.__random):
            random.seed()
            self.__randomRata = random.randint(6,10)/10.0
        print(self.__randomRata)
        if(symbol in self.__alpabeth):
            index = self.__alpabeth.index(symbol)
            if(index == 0):
                #F : Draw forward a 'step' length
                self.__turtle.forward((self.__step/self.__depth) * self.__randomRata)
            if(index == 1):
                #|: Draw forward a 'step'/('factor' * iteration) length
                computeddenom = self.__factor * self.__depth
                computedstep = ((self.__step)/computeddenom) * self.__randomRata                
                self.__turtle.forward(computedstep)
            if(index == 2):
                #G go forward a 'step' length
                self.__turtle.pu()
                self.__turtle.forward(self.__step * self.__randomRata)
                self.__turtle.pd()
            if(index == 3):
                #+ right(angle)
                self.__turtle.right(self.__angle * self.__randomRata)
            if(index == 4):
                self.__turtle.left(self.__angle * self.__randomRata)
            if(index == 5):
                #[ save current position and current angle
                x_coor, y_coor = self.__turtle.xcor(), self.__turtle.ycor()
                angle = self.__turtle.heading()
                self.__depth += 1
                self.__coordinates.append([x_coor,y_coor,angle])
            if(index == 6):
                #] Return to the last saved position
                current = self.__coordinates.pop()
                self.__turtle.pu()
                self.__turtle.setpos(current[0], current[1])
                self.__turtle.seth(current[2])
                self.__turtle.pd()
                self.__depth -= 1
           
    
    def generateColors(self):
        for i in range(0,self.__iterations):
            random.seed()
            r = random.randint(40,255)
            g = random.randint(40,255)
            b = random.randint(40,255)
            rgb = (r,g,b)
            self.__colors.append(rgb)
    
    def draw(self):
        if(self.__color):
            self.__screen.colormode(255)
            self.generateColors()
        else:
            self.__turtle.color(0,0,0)           
        for symbol in self.__axiom:            
            self.mappingIntructions(symbol)
        print("End")
    
    def drawLSystem(self):       
        
        for i in range(0, self.__iterations):
            self.setInstructions()
            print(self.__axiom)
        self.draw()
    